package com.dongqi.camera.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dongqi.camera.dto.CameraDTO;
import com.dongqi.camera.entity.CameraEntity;
import com.dongqi.camera.mapper.CameraEntityMapper;
import com.dongqi.camera.service.CameraService;
import com.dongqi.camera.vo.SafeCameraUrlVo;
import com.dongqi.utils.StringUtils;
import com.dongqi.utils.ezviz.ZJEzvizutil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@Transactional
public class CameraServiceImpl implements CameraService {
    @Autowired
    private CameraEntityMapper cameraEntityMapper;

    @Value("${video.url1}")
    private String videoUrl1;

    @Value("${video.url2}")
    private String videoUrl2;

    @Value("${video.url3}")
    private String videoUrl3;

    @Value("${video.url4}")
    private String videoUrl4;

    @Override
    public List<CameraDTO> queryAll() {
        List<CameraDTO> list = new ArrayList<>();
        List<CameraEntity> cameraEntities = cameraEntityMapper.selectList(null);
        if (cameraEntities.size() > 0) {
            for (CameraEntity cameraEntity : cameraEntities) {
                CameraDTO cameraDTO = new CameraDTO();
                BeanUtils.copyProperties(cameraEntity, cameraDTO);
                list.add(cameraDTO);
            }
        }
        return list;
    }

    @Override
    public SafeCameraUrlVo queryByDeviceNo(String deviceNo) {
        QueryWrapper<CameraEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("device_no", deviceNo);
        CameraEntity cameraEntity = cameraEntityMapper.selectOne(wrapper);
        if (null != cameraEntity) {
            String url = "ezopen://open.ys7.com/" + cameraEntity.getSerialNo() + "/" + cameraEntity.getChannelNo() + ".hd.live";
            cameraEntity.setUrl(url);
            int i = cameraEntityMapper.updateById(cameraEntity);
            if (i > 0) {
                String accessToken = ZJEzvizutil.getAccessToken();
                SafeCameraUrlVo safeCameraUrlVo = new SafeCameraUrlVo(url, accessToken, cameraEntity.getSerialNo(), Integer.parseInt(cameraEntity.getChannelNo()));
                return safeCameraUrlVo;
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    @Override
    public void getVideo1(HttpServletRequest request, HttpServletResponse response) {
        extracted(request, response, videoUrl1);
    }

    @Override
    public void getVideo2(HttpServletRequest request, HttpServletResponse response) {
        extracted(request, response, videoUrl2);
    }

    @Override
    public void getVideo3(HttpServletRequest request, HttpServletResponse response) {
        extracted(request, response, videoUrl3);
    }

    @Override
    public void getVideo4(HttpServletRequest request, HttpServletResponse response) {
        extracted(request, response, videoUrl4);
    }

    private void extracted(HttpServletRequest request, HttpServletResponse response, String videoUrl) {
        try {
            response.reset();
            File file = new File(videoUrl);
            ;
            long fileLength = file.length();
            // 随机读文件
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");

            //获取从那个字节开始读取文件
            String rangeString = request.getHeader("Range");
            long range = 0;
            if (StringUtils.isNotEmpty(rangeString)) {
                range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
            }
            //获取响应的输出流
            OutputStream outputStream = response.getOutputStream();
            //设置内容类型
            response.setHeader("Content-Type", "video/mp4");
            //返回码需要为206，代表只处理了部分请求，响应了部分数据
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

            // 移动访问指针到指定位置
            randomAccessFile.seek(range);
            // 每次请求只返回2MB的视频流
//        System.out.println("每次请求只返回2MB的视频流");
            byte[] bytes = new byte[1024 * 1024 * 2];
            int len = randomAccessFile.read(bytes);
            //设置此次相应返回的数据长度
            response.setContentLength(len);
            //设置此次相应返回的数据范围
            response.setHeader("Content-Range", "bytes " + range + "-" + (fileLength - 1) + "/" + fileLength);
            // 将这1MB的视频流响应给客户端
            outputStream.write(bytes, 0, len);
            outputStream.close();
            randomAccessFile.close();

            System.out.println("返回数据区间:【" + range + "-" + (range + len) + "】");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("视频流传输出现异常！！！");
        }
    }
}
